import { Transform, TransformCallback } from 'stream';

class SliceStream extends Transform {
	_start: number;
	_end: number;
	_offset: number;
	_state: number;
	_emitUp: boolean;
	_emitDown: boolean;
	constructor(start: number, end: number) {
		super();
		this._start = start || 0;
		this._end = end || Infinity;
		this._offset = 0;
		this._state = 0;
		this._emitUp = false;
		this._emitDown = false;
	}
	override _transform(chunk: any, encoding: BufferEncoding, done: TransformCallback): void {
		this._offset += chunk.length;
		if (!this._emitUp && this._offset >= this._start) {
			this._emitUp = true;
			const start = chunk.length - (this._offset - this._start);
			if (this._offset > this._end) {
				const end = chunk.length - (this._offset - this._end);
				this._emitDown = true;
				this.push(chunk.slice(start, end));
			} else {
				this.push(chunk.slice(start, chunk.length));
			}
			return done();
		}
		if (this._emitUp && !this._emitDown) {
			if (this._offset >= this._end) {
				this._emitDown = true;
				this.push(chunk.slice(0, chunk.length - (this._offset - this._end)));
			} else {
				this.push(chunk);
			}
			return done();
		}
		return done();
	}
}

export function slice(start: number, end: number) {
	return new SliceStream(start, end);
}
